package javabase.concurrent;


public class AlarmAgent {

    private final static AlarmAgent INSTANCE = new AlarmAgent();

    private boolean connectedToServer = false;
    private final HeartBeatThread thread = new HeartBeatThread();


    private AlarmAgent(){
        init();
    }

    public static AlarmAgent getInstance() {
        return INSTANCE;
    }

    private void init() {
        connectToServer();
        thread.setDaemon(true);
        thread.start();
    }

    private void connectToServer() {
        new Thread(this::doConnect).start();
    }

    private void doConnect() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (this) {
            System.out.println("connecting to server");
            connectedToServer = true;
            notify();
        }
    }

    public void sendAlarm(String message) throws InterruptedException {
        synchronized (this) {
            while (!connectedToServer) {
                wait();
            }
            doSendAlarm(message);
        }
    }

    private void doSendAlarm(String message) {
        System.out.println("send message : " + message);
    }

    class HeartBeatThread extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                while (true) {
                    if (checkConnection()) {
                        connectedToServer = true;
                    } else {
                        connectedToServer = false;
                        System.err.println("disconnected from server");
                        connectToServer();
                    }
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private boolean checkConnection() {
            boolean isConnected = true;
            if (Math.random()*1000 < 400) {
                isConnected = false;
            }
            return isConnected;
        }
    }

    public static void main(String[] args) {
        try {
            AlarmAgent.INSTANCE.sendAlarm("hhh");
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
